package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 判断一个元素是否在某个切片中
func isInSlice(target int, str_array []int) bool {
	for i := 0; i < len(str_array); i++ {
		if str_array[i] == target {
			return true
		}
	}
	return false
}

// 去重后切片排序
func sortSlice(target []int) []int {
	// length = len(list)
	// for i in range(length - 1, 0, -1):
	//   for j in range(i):
	// 	if list[j] > list[i]:
	// 	  list[j], list[i] = list[i], list[j]

	length := len(target)
	for i := 0; i < length; i++ {
		for j := 0; j < i; j++ {
			if target[j] > target[i] {
				target[j], target[i] = target[i], target[j]
			}
		}
	}

	return target

}

// 计算去重后切片的每个元素，在原始切片中的次数
func countUniqueSlice(target []int, sourceSlice []int, dicNums map[int]int) map[int]int {
	for i := 0; i < len(target); i++ {
		for j := 0; j < len(sourceSlice); j++ {
			if target[i] == sourceSlice[j] {
				dicNums[target[i]] += 1
			}
		}
	}
	return dicNums
}

func main() {
	/* 作业
	1、看下面一段程序，回答问题
	s1 := make([]int, 3, 4)
	s2 := append(s1, 1)

	请问s1、s2内各有什么元素？
	解答：s1:[0,0,0] s2:[0,0,0,1]

	s1修改一个元素会影响s2吗？s2修改一个元素会影响s1吗？
	解答：s1修改一个元素不会影响s2，s2修改一个元素会影响s1

	s2再增加一个元素会怎么样？
	解答：s2再增加一个元素会新开辟一块内存地址存储新的底层数组，将s1的元素cp过来，再将新增的元素append到这个底层数组
	*/
	// =======================================分割线==============================================================
	//2、有一个数组 [1,4,9,16,2,5,10,15]，生成一个新切片，要求新切片元素是数组相邻2项的和。
	// s1 := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	// s2 := s1[:]

	// for i := 0; i < len(s2)-1; i++ {
	// 	fmt.Println(s2[i] + s2[i+1])
	// }
	// =======================================分割线==============================================================
	// 3、数字重复统计
	/*题目
	随机产生100个整数
	数字的范围[-100, 100]
	降序输出这些生成的数字并打印其重复的次数
	*/
	//生成100个[-100, 100]随机整数
	randNums := make([]int, 0, 100)
	new_randNums := make([]int, 0, 100)

	var count int
	// sort_randNums := make([]int, 0, count)
	for i := 0; i < 100; i++ {
		rand.New(rand.NewSource(time.Now().UnixNano())) // 利用当前时间的纳秒值做种子
		n := rand.Intn(201) - 100
		randNums = append(randNums, n)
	}

	// 计算去重之后元素个数，并排序生成新的切片
	for i := 0; i < len(randNums); i++ {
		if i == 0 {
			new_randNums = append(new_randNums, randNums[i])
			count += 1
		} else {
			flag := isInSlice(randNums[i], new_randNums)
			if flag {
				continue
			} else {
				new_randNums = append(new_randNums, randNums[i])
				count += 1
			}
		}
	}
	// fmt.Println(count, new_randNums)
	sort_randNums := sortSlice(new_randNums)
	sliceCountMap := make(map[int]int, count)
	countUniqueSlice(sort_randNums, randNums, sliceCountMap)

	//降序输出
	for i := len(sort_randNums) - 1; i > 0; i-- {
		fmt.Println(sort_randNums[i], sliceCountMap[sort_randNums[i]])
	}
	// =======================================分割线==============================================================
	//4、简述线性数据结构和哈希表优劣
	/*
		线性数据结构分为以下两种：
			顺序表：
				优点：查询快，通过索引直接查找；有序添加，允许重复；
				缺点：在中间或头部位添加、删除动作较大，；
			链表：
				优点：有序添加、增删改速度快，对于链表数据结构，增加和删除只要修改元素中的指针就可以了；
				缺点：查询慢，如果要访问链表中一个元素，就需要从第一个元素开始查找；
		哈希：
			特点：散列表，不允许重复；
			优点：如果关键字已知则存取速度极快；
			缺点：如果不知道关键字则存取很慢，对存储空间使用不充分；
	*/
}

// 阿飞老师的批改
// 1. s1修改会影响s2，s2修改最后不影响s1
// 2. 随机数范围不符合要求
